<?php
/**
 * This file contains the class SourceViewEditor
 *
 *@package TextEditor
 */
/**
 * Utilities to work with files
 */
require_once(dirname(__FILE__) . "/common/FileUtils.php");

/**
 * This class is a editor using GtkSourceView
 *
 *@package TextEditor
 */ 
class SourceViewEditor extends GtkVBox implements EditorInterface
{
    /**
     * The current file name
     */
    private $filename;
    
    /**
     * If the text is marked as modified
     */
    private $markModified;
    
    /**
     * Constructor
     */
    public function __construct()
    {
         parent::__construct();
         $this->buildGUI();
    }
    
    /**
     * Build the gui
     *
     *@todo make the font name and size come from some preference
     *@todo make insert_spaces_instead_of_tabs como from some preference(this
     *      in true break a Makefile)
     */
    private function buildGUI()
    {         
         $this->markModified = false;
        
         $this->label = new GtkLabel("New File");
         $this->pack_start($this->label, false, false, 10);
         
         $this->buffer = new GtkSourceBuffer();
         $this->editor = GtkSourceView::new_with_buffer($this->buffer);
         
         $this->buffer->connect_simple(      'changed',         array($this,'onModified'));
         $this->editor->connect_simple(      'key-press-event', array($this,'onKeyPress'));
         $this->editor->connect_simple_after('move-cursor',     array($this,'onMoveCursor'));
         
         $this->editor->set_show_line_numbers(true);
         $this->editor->set_show_line_markers(true);
         $this->editor->set_auto_indent(true);
         $this->editor->set_insert_spaces_instead_of_tabs(true);
         $font = new PangoFontDescription ("Courier New Bold  10");
         $this->editor->modify_font($font);
         
         $this->sc = new GtkScrolledWindow();
         $this->sc->add($this->editor);
         
         $this->pack_start($this->sc, true, true, 10);
         
         $this->show_all();
    }
 
    /**
     * Return the content
     */
    public function getContents()
    {
        $buff = $this->editor->get_buffer();
        return($buff->get_text($buff->get_start_iter(), $buff->get_end_iter()));  
    }
    
    /**
     * Return the current open file
     */
    public function getFilename()
    {
        return($this->filename);
    }
    
    /**
     * Query if the content is modified
     */
    public function isModified()
    {
        return($this->buffer->get_modified());
    }
    
    /**
     * Load a file
     *
     *@param string $filename The name of the file
     *@param string $text     The content of the file
     */
    public function load($filename, $text)
    {
        $this->loading = true;
        $event = Event::singleton();
        $args["filename"] = $filename;
        
        $continue = $event->post("before_load" , $args);
        
        $lm = new GtkSourceLanguagesManager();
        $la = $lm->get_language_from_mime_type(FileUtils::getMimeType($filename));
       
        $this->buffer->set_language($la);
        $this->buffer->set_highlight(true);
        $this->buffer->set_text($text);
        $this->filename = $filename;
        $this->label->set_text($this->filename);
        $this->markModified = false;
        $this->loading = false;
        $this->buffer->set_modified(false);
   }

    /**
     * When the user press a key
     *
     * Simple post this event for the TextEditor handle it
     *@access private
     */
    public function onKeyPress()
    {
        $evt = Gtk::get_current_event();
        $Myevent = Event::singleton();
        $args["key"] = chr($evt->keyval);
        $args["state"] = $evt->state;
        $continue = $Myevent->post("key_press" , $args);
        $this->onMoveCursor(1);
    }
    
    /**
     * When the contents change.
     *
     * Simple post this event for the TextEditor handle it and
     * show the file as modified
     *@access private
     */
    public function onModified()
    {
        if (!$this->markModified && !$this->loading) {
            $this->label->set_text($this->label->get_text() . " *");
            $this->markModified = true;
            
            $event = Event::singleton();
            $args = array();
            $continue = $event->post("modified" , $args);
            $this->onMoveCursor();
        }
    }
    
    /**
     * When the cursor change the position
     *
     *@access private
     */
    public function onMoveCursor($offset = 0)
    {
        $iter = $this->buffer->get_iter_at_mark($this->buffer->get_insert());
	$args["line"] = $iter->get_line() + 1;		
	$args["col"] = $iter->get_line_offset() + 1 + $offset;
	$event = Event::singleton();
	$event->post("update-line-column", $args);
    }
    	
    /**
     * When the content is save
     */
    public function save()
    {
        $this->label->set_text($this->filename);
        $buff = $this->editor->get_buffer();
        $buff->set_modified(false);
        $this->markModified = false;
    }

    /**
     * When the content is save with a new name
     */
    public function saveAs($filename)
    {
        $this->filename = $filename;
        $this->label->set_text($this->filename);
        
        $lm = new GtkSourceLanguagesManager();
        $la = $lm->get_language_from_mime_type(FileUtils::getmimeType($filename));
        
        $this->buffer->set_language($la);
        $this->buffer->set_highlight(true);
        $this->buffer->set_modified(false);
        $this->markModified = false;
    }
}